﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once

#include "ElementId.h"
#include "UniIdentity.h"
#include "IGraphicsStyleData.h"
#include "IGraphicsNodeStyleAndMaterialCustomizer.h"

namespace gcmp
{
    class IUiView;
    class IDocument;
    class IElement;
    class ICategory;
    class IGraphicsNode;
    class IGraphicsStyle;
    class IGraphicsElementShape;
    class IGraphicsNodeReference;
    class IGraphicsStyleDataOverrideItems;
    class IGraphicsStyleDataValiditySettings;
}

namespace Sample
{
    class CustomizerGStyleManager;

    // 图形节点按照类别或名称重载
    enum class GNodeGStyleOverrideType
    {
        ByGraphicsStyleName,
        ByGraphicsStyleCategory,
    };

    // 包含GStyleViewerUtils和GraphicsStyleTable之间传递的数据
    // 该数据对应GraphicsStyleTable不同TAB中的一行数据
    struct GraphicsOverrideData
    {
    public:
        gcmp::OwnerPtr<gcmp::IGraphicsStyleData>                    m_opGStyleData;
        gcmp::OwnerPtr<gcmp::IGraphicsStyleDataOverrideItems>       m_opGStyleDataOverrideItems;
        gcmp::OwnerPtr<gcmp::IGraphicsStyleDataValiditySettings>    m_opGStyleDataValiditySettings;
        
        // 图形节点是否有样式和样式名称
        bool m_hasGNodeText;
        // 图形节点的样式名称
        std::wstring m_gNodeText;
        
        // 图形节点是否有类别和类别名称
        bool m_hasGNodeCategory;
        // 图形节点的样式类别
        const gcmp::ICategory* m_gNodeCategory;

        // 该级显示样式是否可设置，例如如果图形节点没有显示样式，那么图形节点级的各种重载都不可用。或者图元无法获得显示样式重载器
        bool m_available;

        // 图形节点的显示样式Id
        gcmp::ElementId m_gStyleId;

        GraphicsOverrideData(gcmp::OwnerPtr<gcmp::IGraphicsStyleData> opGStyleData)
            : GraphicsOverrideData()
        {
            m_opGStyleData = TransferOwnership(opGStyleData);
        }

        GraphicsOverrideData()
            : m_opGStyleData(nullptr)
            , m_opGStyleDataOverrideItems(nullptr)
            , m_opGStyleDataValiditySettings(nullptr)
            , m_gNodeText(L"")
            , m_hasGNodeText(false)
            , m_gNodeCategory(nullptr)
            , m_hasGNodeCategory(false)
            , m_available(true)
            , m_gStyleId(gcmp::ElementId::InvalidID)
        {

        }
    };

    // 显示样式重载机制的主要示例代码都在这里
    class GStyleViewerUtils
    {
    public:
        GStyleViewerUtils(gcmp::IUiView* pCurrentView, gcmp::ElementId elemId, const gcmp::IGraphicsNode* gNode);

        // 图形节点的显示样式重载数据获得
        // 根据文档/视图，以及图形节点通过样式名称/样式类别，获得对应的显示样式重载数据
        gcmp::OwnerPtr<GraphicsOverrideData> GetCustomizerData(gcmp::GraphicsStyleOverrideGrade gStyleOverrideGrade, GNodeGStyleOverrideType overrideType);

        // 图形节点的显示样式重载数据设置
        // 根据文档/视图，以及图形节点通过样式名称/样式类别，设置对应的显示样式重载数据
        bool SetCustomizerData(gcmp::OwnerPtr<GraphicsOverrideData>& opOverrideData,
            GNodeGStyleOverrideType overrideType, gcmp::GraphicsStyleOverrideGrade gStyleOverrideGrade);

        // 获得共9种显示样式设置的数据：(文档/视图) x (类别/图元/图形节点按样式名称/图形节点按样式类别) + 图形节点直接设置
        std::vector<gcmp::OwnerPtr<GraphicsOverrideData>> GetGStyles(bool canGNodeSetDirectly);

        // 将从对话框中设置的9种显示样式的数据设置到GDMP数据层
        void SetGStyles(std::vector<gcmp::OwnerPtr<GraphicsOverrideData>> gOverrideDataList, bool canGNodeSetDirectly, gcmp::OwnerPtr<gcmp::IGraphicsElementShape> cachedGRep = nullptr);

        // 类别是否可以有显示样式。有些类别只是辅助用，没有显示。
        bool CanCategoryHaveGraphicsMaterial(const gcmp::IDocument* pDocument, const gcmp::UniIdentity& categoryUid) const;

        // 获得文档中所有的填充名称
        static void GetHatchPatternNames(gcmp::IDocument* pDoc, std::vector<std::wstring>& hatchPatternNames);
    private:
        gcmp::IElement* GetElement();
    private:
        // 文档
        gcmp::IDocument* m_pDocument;
        // 视图
        gcmp::IUiView* m_pUiView;

        // 类别
        gcmp::UniIdentity m_categoryId;
        // 图元
        const gcmp::ElementId m_elemId;
        // 图形节点
        const gcmp::IGraphicsNode* m_pGNode;
    };
}

